package service

import (
	"GoKill/help"
	"GoKill/models"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	uuid "github.com/satori/go.uuid"
	"gorm.io/gorm"
	"net/http"
	"strconv"
	"time"
)

func SecKill(c *gin.Context) {
	var product models.Product
	token := c.GetHeader("token")
	userClaims, err2 := help.AnalyseToken(token)
	if err2 != nil {
		fmt.Println(err2)
	}
	userId := userClaims.Id
	//时间标准
	layout := "2006-01-02T15:04:05"
	//定义读写锁
	rw := models.Rw
	id, _ := strconv.Atoi(c.Param("id"))
	//查询商品,可以优化为redis
	product = SelectProById(id)
	//把时间字符串转为time。time类型
	t, err := time.Parse(layout, product.StartTime[:19])
	if err != nil {
		fmt.Println("解析时间时出错:", err)
		return
	}
	if time.Now().Before(t) {
		c.JSON(http.StatusOK, gin.H{
			"err": "时间没到",
		})
		return
	}
	//直接加锁，也可以利用数据库枷锁
	rw.Lock()
	//加事务
	if err := models.DB.Transaction(func(tx *gorm.DB) error {
		//一人·一单
		result, _ := models.RDB.Get(c, "order:"+strconv.Itoa(int(userId))).Result()
		fmt.Println(result)
		if result != "" {
			c.JSON(http.StatusOK, gin.H{
				"data": "一人一单",
			})
			return nil
		}
		//判断库存
		if product.ProductNum < 1 {
			c.JSON(http.StatusOK, gin.H{
				"data": "库存不足",
			})
			return nil
		}
		var OUP models.ProUser
		OUP.UserID = userId
		OUP.ProductID = product.ID
		OUjson, _ := json.Marshal(OUP)
		help.Publish("GO-order", "EX-order", "111", string(OUjson))
		rw.Unlock()
		//生成唯一id
		orderId := uuid.NewV4()
		//存入redis
		models.RDB.Set(c, "order:"+strconv.Itoa(int(userId)), orderId.String(), 0)
		c.JSON(http.StatusOK, gin.H{
			"data": "抢购成功",
		})
		return nil
	}); err != nil {
		c.JSON(200, gin.H{
			"code": -1,
			"msg":  "更新问题错误" + err.Error(),
		})
		return
	}
}
